﻿using System;
using System.Threading;
using System.Threading.Tasks;

namespace Fast.Threading
{
    /// <summary>
    /// 线程信号量扩展方法
    /// </summary>
    [SkipScan]
    public static class SemaphoreSlimExtensions
    {
        /// <summary>
        /// 异步锁 锁住的代码块可以执行await/async方法
        /// </summary>
        /// <param name="semaphoreSlim"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static async Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken)
        {
            await semaphoreSlim.WaitAsync(cancellationToken);
            return GetDispose(semaphoreSlim);
        }

        /// <summary>
        /// 同步锁 和用lock、Monitor一个效果
        /// </summary>
        /// <param name="semaphoreSlim"></param>
        /// <returns></returns>
        public static IDisposable Lock(this SemaphoreSlim semaphoreSlim)
        {
            semaphoreSlim.Wait();
            return GetDispose(semaphoreSlim);
        }

        private static IDisposable GetDispose(this SemaphoreSlim semaphoreSlim)
        {
            return new DisposeAction(() =>
            {
                semaphoreSlim.Release();
            });
        }
    }
}
